#include "global.h"

/* 硬件配置 */
#define LED_NUM 4 // 系统支持的LED数量

#define PWM_MAX 1000 - 1 // PWM占空比最大值（对应100%亮度）
#define PWM_MIN 0        // PWM占空比最小值（对应0%亮度）

/* 呼吸模式参数 */
#define BREATH_STEP 4 // 每个tick的亮度变化步长

/* 标准闪烁模式参数 */
#define BLINK_ON_TICKS 40                                    // 持续亮灯时间
#define BLINK_OFF_TICKS 60                                   // 持续灭灯时间
#define BLINK_TOTAL_TICKS (BLINK_ON_TICKS + BLINK_OFF_TICKS) // 完整周期

/* 双闪模式参数 */
#define DOUBLE_BLINK_FAST_TICKS 20                                                        // 快闪阶段单次亮/灭持续时间
#define DOUBLE_BLINK_PAUSE_TICKS 120                                                      // 两次快闪后的长灭时间
#define DOUBLE_BLINK_TOTAL_TICKS (4 * DOUBLE_BLINK_FAST_TICKS + DOUBLE_BLINK_PAUSE_TICKS) // 完整周期

/* LED 状态控制器数组 */
static _st_LEDInfo led[LED_NUM];

/**
 * @brief 初始化所有 LED
 *
 * 该函数初始化所有 LED 的状态，确保它们处于关闭状态，并设置初始参数。
 * 具体操作包括：
 * 1. 将每个 LED 的模式设置为关闭（LEDMODE_OFF）。
 * 2. 将每个 LED 的 PWM 占空比设置为最小值（PWM_MIN），即完全关闭。
 * 3. 将每个 LED 的呼吸模式方向初始化为渐亮（breathDirection = 1）。
 * 4. 将每个 LED 的闪烁计数器初始化为 0。
 * 5. 调用 led_setMode 函数确保 LED 状态正确设置为关闭。
 */
void led_init(void)
{
    for (int i = 0; i < LED_NUM; i++)
    {
        led[i].mode = LEDMODE_OFF;        // 设置模式为关闭
        led[i].compare = PWM_MIN;         // 设置 PWM 占空比为最小值
        led[i].breathDirection = 1;       // 初始化呼吸模式方向为渐亮
        led[i].blinkCounter = 0;          // 初始化闪烁计数器为 0
        led_setMode(i, LEDMODE_OFF);      // 确保 LED 状态正确设置为关闭
    }
}

/**
 * @brief 设置指定 LED 的工作模式
 *
 * @param id LED 编号（0~LED_NUM-1）
 * @param mode 要设置的模式类型
 *
 * 初始化说明：
 * - 呼吸模式：从最低亮度开始渐亮
 * - 闪烁模式：计数器从 0 开始，确保首次完整亮灭周期
 * - 双闪模式：包含两次快闪后长灭的完整周期
 */
void led_setMode(uint8_t id, _em_LEDMode mode)
{
    if (id < LED_NUM)
    {
        led[id].mode = mode;

        switch (mode)
        {
        case LEDMODE_ON:
            led[id].compare = PWM_MAX / 2; // 常亮
            break;

        case LEDMODE_OFF:
            led[id].compare = PWM_MIN; // 完全关闭
            break;

        case LEDMODE_BREATH:
            led[id].compare = PWM_MIN;   // 从最低亮度开始
            led[id].breathDirection = 1; // 初始方向为渐亮
            break;

        case LEDMODE_BLINK:
            led[id].compare = PWM_MAX; // 初始状态为亮
            led[id].blinkCounter = 0;  // 计数器归零
            break;

        case LEDMODE_DOUBLE_BLINK:
            led[id].compare = PWM_MAX; // 初始状态为亮
            led[id].blinkCounter = 0;  // 计数器归零
            break;
        }
    }
}

/**
 * @brief LED 状态机核心处理函数（需周期性调用）
 *
 * 该函数周期性调用，根据当前模式更新 LED 的亮度。
 * 工作模式说明：
 * - 呼吸模式：锯齿波变化，亮度平滑过渡
 * - 闪烁模式：固定占空比方波
 * - 双闪模式：快闪两次
 */
void led_ticks(void)
{
    for (int i = 0; i < LED_NUM; i++)
    {
        switch (led[i].mode)
        {
        case LEDMODE_BREATH:
            /* 呼吸灯亮度渐变处理 */
            if (led[i].breathDirection == 1)
            {
                // 渐亮阶段
                led[i].compare = (led[i].compare + BREATH_STEP > PWM_MAX)
                                     ? PWM_MAX // 达到峰值后反转方向
                                     : led[i].compare + BREATH_STEP;
                if (led[i].compare == PWM_MAX)
                    led[i].breathDirection = -1;
            }
            else
            {
                // 渐暗阶段
                led[i].compare = (led[i].compare - BREATH_STEP < PWM_MIN)
                                     ? PWM_MIN // 达到谷值后反转方向
                                     : led[i].compare - BREATH_STEP;
                if (led[i].compare == PWM_MIN)
                    led[i].breathDirection = 1;
            }
            break;

        case LEDMODE_BLINK:
            /* 标准闪烁模式状态机 */
            led[i].blinkCounter = (led[i].blinkCounter + 1) % BLINK_TOTAL_TICKS;
            led[i].compare = (led[i].blinkCounter < BLINK_ON_TICKS)
                                 ? PWM_MAX  // 亮灯阶段
                                 : PWM_MIN; // 灭灯阶段
            break;

        case LEDMODE_DOUBLE_BLINK:
            /* 双闪模式状态机 */
            led[i].blinkCounter = (led[i].blinkCounter + 1) % DOUBLE_BLINK_TOTAL_TICKS;

            if (led[i].blinkCounter < DOUBLE_BLINK_FAST_TICKS)
            {
                led[i].compare = PWM_MAX; // 第一次亮
            }
            else if (led[i].blinkCounter < 2 * DOUBLE_BLINK_FAST_TICKS)
            {
                led[i].compare = PWM_MIN; // 第一次灭
            }
            else if (led[i].blinkCounter < 3 * DOUBLE_BLINK_FAST_TICKS)
            {
                led[i].compare = PWM_MAX; // 第二次亮
            }
            else if (led[i].blinkCounter < 4 * DOUBLE_BLINK_FAST_TICKS)
            {
                led[i].compare = PWM_MIN; // 第二次灭
            }
            else
            {
                led[i].compare = PWM_MIN; // 长灭等待阶段
            }
            break;

        // ON/OFF 模式无需处理，保持当前状态
        default:
            break;
        }

        /* 更新硬件 PWM 输出 */
        switch (i)
        {
        case 0:
            pwmLED_setCompare1(led[i].compare);
            break;
        case 1:
            pwmLED_setCompare2(led[i].compare);
            break;
        case 2:
            pwmLED_setCompare3(led[i].compare);
            break;
        case 3:
            pwmLED_setCompare4(led[i].compare);
            break;
        }
    }
}
